package bjut.core.handler;

import bjut.core.factory.SingletonFactory;
import bjut.core.Message.RpcRequest;
import bjut.core.interfaces.ServiceProvider;
import bjut.core.zookeeper.ZkServiceProviderImpl;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @Author: zhuzhiming
 * @Date: 2022/5/14 23:01
 */
public class RpcRequestHandler {

    private final ServiceProvider serviceProvider;

    public RpcRequestHandler() {
        serviceProvider = SingletonFactory.getInstance(ZkServiceProviderImpl.class);
    }


    public Object handle(RpcRequest rpcRequest) {

        Object service = null;
        try {
            service = serviceProvider.getService(rpcRequest.getRpcServiceName());
        } catch (Exception e) {
            e.printStackTrace();
        }
        assert service != null;
        return invokeTargetMethod(rpcRequest, service);
    }

    private Object invokeTargetMethod(RpcRequest rpcRequest, Object service) {
        Object result;
        try {
            Method method = service.getClass().getMethod(rpcRequest.getMethodName(), rpcRequest.getParamTypes());
            result = method.invoke(service, rpcRequest.getParameters());
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            throw new RuntimeException(e.getMessage());
        }
        return result;
    }

}
